package vaadin.lab2;

import java.util.HashSet;
import java.util.Set;

import com.vaadin.Application;
import com.vaadin.terminal.Sizeable;
import com.vaadin.ui.AbstractOrderedLayout;
import com.vaadin.ui.Alignment;
import com.vaadin.ui.Button;
import com.vaadin.ui.Button.ClickEvent;
import com.vaadin.ui.VerticalLayout;
import com.vaadin.ui.Window;
import com.vaadin.ui.Window.CloseEvent;
import com.vaadin.ui.Window.CloseListener;

@SuppressWarnings("serial")
public class Lab extends Application {

    private static final int NUM_WINDOWS_IN_ROW = 5;
    private static final int WINDOW_BASE_Y = 150;
    private static final int WINDOW_WIDTH = 200;
    private static final int WINDOW_HEIGHT = 150;

    private int numWindows = 0;
    private Window firstWindow;
    private VerticalLayout mainLayout = new VerticalLayout();

    @Override
    public void init() {
        Window mainWindow = new Window("Lab", mainLayout);
        setMainWindow(mainWindow);
        buildLayout();
    }

    private void buildLayout() {
        Button addMoreWindowsButton = new Button("Add more windows",
                createAddWindowListener());
        firstWindow = new Window();
        firstWindow.setWidth("100%");
        firstWindow.addComponent(addMoreWindowsButton);
        if (firstWindow.getContent() instanceof AbstractOrderedLayout) {
            ((AbstractOrderedLayout) firstWindow.getContent())
                    .setComponentAlignment(addMoreWindowsButton,
                            Alignment.MIDDLE_CENTER);
        }

        firstWindow.addListener(new CloseListener() {

            public void windowClose(CloseEvent e) {
                Window parentWindow = getMainWindow();
                Set<Window> children = new HashSet<Window>(parentWindow
                        .getChildWindows());
                for (Window w : children) {
                    parentWindow.removeWindow(w);
                }
            }
        });

        Button addWindowButton = new Button("Add a Window",
                new Button.ClickListener() {

                    public void buttonClick(ClickEvent event) {
                        if (firstWindow.getParent() == null) {
                            numWindows = 0;
                            getMainWindow().addWindow(firstWindow);
                        }
                    }
                });
        mainLayout.addComponent(addWindowButton);
    }

    private Button.ClickListener createAddWindowListener() {
        return new Button.ClickListener() {
            public void buttonClick(ClickEvent event) {
                getMainWindow().addWindow(createAdditionalWindow());
            }
        };
    }

    private Window createAdditionalWindow() {
        Window w = new Window();
        w.setWidth(WINDOW_WIDTH, Sizeable.UNITS_PIXELS);
        w.setHeight(WINDOW_HEIGHT, Sizeable.UNITS_PIXELS);
        w.setPositionX(getPositionX(numWindows));
        w.setPositionY(getPositionY(numWindows));
        numWindows++;
        return w;
    }

    private static int getPositionX(int n) {
        return n % NUM_WINDOWS_IN_ROW * WINDOW_WIDTH;
    }

    private static int getPositionY(int n) {
        return n / NUM_WINDOWS_IN_ROW * WINDOW_HEIGHT + WINDOW_BASE_Y;
    }

}
